/**
 * 所有版权归 广西梧州 陈锦韬 所有
 *
 * @Title: CommonService
 * @Package com.rx.stang.service
 * @Description: 公共接口
 * @author: 陈锦韬
 * @date: 2022/4/17
 * @version V1.0
 * @Copyright: 2022 陈锦韬  All rights reserved.
 */
package com.rx.stang.service;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.rx.core.base.RxBaseConstant;
import com.rx.core.base.RxBaseData;
import com.rx.core.base.RxResponse;
import com.rx.core.enm.HANDLER_TYPE;
import com.rx.core.enm.RX_DB_OPERATE;
import com.rx.core.enm.RX_STATUS;
import com.rx.core.iface.RelationQuery;
import com.rx.core.service.RxBaseAbstractService;
import com.rx.core.service.StandardService;
import com.rx.core.util.EmptyChecker;
import com.rx.core.util.RxUtil;
import com.rx.stang.bean.ReadProperties;
import com.rx.stang.bean.RxMainConfigBean;
import com.rx.stang.dto.FileInfoResult;
import com.rx.stang.emn.ARTICLE_TYPE;
import com.rx.stang.emn.NOUS_TYPE;
import com.rx.stang.handler.SuiTangHandler;
import com.rx.stang.vo.*;
import com.rx.stang.vo.relation.DoubleTangArticleInfo;
import com.rx.stang.vo.relation.DoubleTangNousInfo;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.FileUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;
import java.io.*;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author: CHENJINTAO170
 * @Description: 公共接口
 * @date: 2022/4/17
 */
@Slf4j
@Service
public class STangCommonService extends RxBaseAbstractService {
    public static final String  NEWEST="1";
    public static final String  SPACE=" ";
    public static final String  OLDE="0";
    public static final String  HAS_STAGE="1";
    public static final String BOOK_TYPE_MENG="00";
    public static final int MIN_RETURN_SIZE = 15;

    @Autowired
    StandardService standardService;

    @Autowired
    SuiTangHandler suiTangHandler;

    @Autowired
    RxMainConfigBean rxMainConfigBean;

    private Set<Integer> getRandomSet(int count,int size,boolean startWithZero){
        Random rand =new Random(System.currentTimeMillis());
        Set<Integer> idSet = new HashSet<>();
        while (idSet.size() < count){
            int idRandom = rand.nextInt(size) + (startWithZero?0:1);
            idSet.add(idRandom);
        }
        return idSet;
    }
    private IPage searchRandomPage(RxBaseData condition,int pageSize,int randRage){
        Random rand =new Random(System.currentTimeMillis());
        condition.setPageSize(pageSize);
        // 1000个人物为一页。随机选择一页。从这一页中随机选择20个
        int idRandomPage = rand.nextInt(randRage) + 1;
        condition.setPageNum(idRandomPage);
        IPage iPage = (IPage)standardService.searchPage(condition);
        return iPage;
    }
    private Object ramdonTangNousInfo(int size,int pageSize,Integer nousType) throws InstantiationException, IllegalAccessException {
        Integer maxId = new Integer(MIN_RETURN_SIZE);
        TangNousInfo condition;
        try {
            condition = (TangNousInfo) RxBaseData.create(TangNousInfo.class, HANDLER_TYPE.SINGLE_COUNT);
            condition.setType(nousType);
            maxId = (Integer)standardService.count(condition);
        } catch (Throwable e) {
            maxId = 100;
        }

        condition = (TangNousInfo) RxBaseData.create(TangNousInfo.class, HANDLER_TYPE.SINGLE_PAGE);
        condition.setType(nousType);
        IPage iPage = searchRandomPage(condition,pageSize,maxId/pageSize + 1);
        Set<Integer> idSet = getRandomSet(size,iPage.getRecords().size(),true);
        List<TangNousInfo> resultList = new ArrayList<>();
        for (Integer integer : idSet) {
            resultList.add((TangNousInfo)iPage.getRecords().get(integer));
        }
        return resultList;
    }
    public Object externalPerson() throws InstantiationException, IllegalAccessException {

        int size=20;
        int pageSize=200;
        try{
            return ramdonTangNousInfo(size,pageSize,NOUS_TYPE.PERSON.getValue());
        }catch (Throwable e){

        }

        TangNousInfo condition;
        Integer maxId = 200;
        Set<Integer> idSet = getRandomSet(size,maxId,false);
        condition = (TangNousInfo) RxBaseData.create(TangNousInfo.class, HANDLER_TYPE.SINGLE_LIST);
        Map<String,Object> conditionMap = new HashMap<>();
        condition.setType(NOUS_TYPE.PERSON.getValue());
        conditionMap.put("inId",new ArrayList(idSet));
        condition.setCondition(conditionMap);
        return standardService.searchList(condition);

    }
    public Object externalEvent() throws InstantiationException, IllegalAccessException {
        int size=15;
        int pageSize=200;
        return ramdonTangNousInfo(size,pageSize,NOUS_TYPE.EVENT.getValue());
    }
    private Object ramdonArticleInfo(int size,int pageSize,String articleType) throws InstantiationException, IllegalAccessException {
        Integer maxId = new Integer(MIN_RETURN_SIZE);
        TangArticleInfo condition;
        Random rand =new Random(System.currentTimeMillis());
        try {
            condition = (TangArticleInfo) RxBaseData.create(TangArticleInfo.class, HANDLER_TYPE.SINGLE_COUNT);
            condition.setType(articleType);
            maxId = (Integer)standardService.count(condition);
        } catch (Throwable e) {
            maxId = 100;
        }

        condition = (TangArticleInfo) RxBaseData.create(TangArticleInfo.class, HANDLER_TYPE.SINGLE_PAGE);
        condition.setType(articleType);

        IPage iPage = searchRandomPage(condition,pageSize,maxId/pageSize + 1);
        Set<Integer> idSet = getRandomSet(size,iPage.getRecords().size(),true);
        List<DoubleTangArticleInfo> resultList = new ArrayList<>();
        for (Integer integer : idSet) {
            DoubleTangArticleInfo one = new DoubleTangArticleInfo();
            RxUtil.copyProperties(iPage.getRecords().get(integer),one);
            resultList.add(one);
        }
        return resultList;
    }
    public Object externalPoetry() throws InstantiationException, IllegalAccessException {
        int size=3;
        int pageSize=80;
        // 从80首诗中选3首
        List<DoubleTangArticleInfo> result =  ( List<DoubleTangArticleInfo>)ramdonArticleInfo(size,pageSize, ARTICLE_TYPE.SHI.getValue());
        if(EmptyChecker.isEmpty(result)){
            return result;
        }
        try {
            TangNousInfo condition = (TangNousInfo) RxBaseData.create(TangNousInfo.class, HANDLER_TYPE.SINGLE_LIST);
            Map<String, Object> conditionMap = new HashMap<>();
            condition.setType(NOUS_TYPE.PERSON.getValue());
            conditionMap.put("inName", result.stream().map(DoubleTangArticleInfo::getAuthor).collect(Collectors.toList()));
            condition.setCondition(conditionMap);
            List<TangNousInfo> authorList = (List<TangNousInfo>) standardService.searchList(condition);
            if(EmptyChecker.isEmpty(authorList)){
                return result;
            }

            for (DoubleTangArticleInfo doubleTangArticleInfo : result) {
                for (TangNousInfo tangNousInfo : authorList) {
                   if(doubleTangArticleInfo.getAuthor().equalsIgnoreCase(tangNousInfo.getName())){
                       TangNousInfo newNous = new TangNousInfo();
                       RxUtil.copyProperties(tangNousInfo,newNous);
                       doubleTangArticleInfo.setRelation(newNous);
                       break;
                   }
                }
            }
        }catch (Exception e){

        }


        return result;
    }

    public Object externalAnnualTag(DoubleTangNousInfo param) throws InstantiationException, IllegalAccessException {

        // 双表内连接查询UuaRoleInfo，UuaRelUserRole
        DoubleTangNousInfo conditionDouble = (DoubleTangNousInfo)RxBaseData.create(DoubleTangNousInfo.class, TangTagInfo.class,HANDLER_TYPE.DOUBLE_LIST);
        // 设置条件。
        RxUtil.copyProperties(param,conditionDouble);
        List<DoubleTangNousInfo> resultList;
        if (EmptyChecker.notEmpty(param.getTag())){
            Map<String,Object> map = new HashMap();
            if (param.getTag().contains(SPACE)){
                List<String> tagList = new ArrayList<>();
                for (String oneTag : param.getTag().split(SPACE)) {
                    oneTag = oneTag.replace(SPACE,"");
                    tagList.add(oneTag);
                }
                map.put("inTag",tagList);
            }else {
                map.put("likeRightTag",param.getTag());
            }
            ((TangTagInfo) ((RelationQuery) conditionDouble).obtainRelation()).setCondition(map);

            ((TangTagInfo) ((RelationQuery) conditionDouble).obtainRelation()).setStatus(RX_STATUS.NORMAL.getCode());
            // 不需要返回第二张表的列
            conditionDouble.removeSecondTableField();
            resultList = (List<DoubleTangNousInfo>)standardService.innerSearchList(conditionDouble);

        }else {

            TangNousInfo condition = (TangNousInfo) RxBaseData.create(TangNousInfo.class, HANDLER_TYPE.SINGLE_LIST);
            RxUtil.copyProperties(param,condition);
            Object object = standardService.searchList(condition);
            if (object instanceof RxResponse){
                return object;
            }
            List<TangNousInfo> tangNousInfoList =  (List<TangNousInfo>) object;
            resultList = new ArrayList<>();
            for (TangNousInfo tangNousInfo : tangNousInfoList) {
                resultList.add(DoubleTangNousInfo.create(tangNousInfo));
            }
        }

        if(EmptyChecker.notEmpty(resultList)){
            List<String> bidList = resultList.stream()
                    .filter(e->HAS_STAGE.equals(e.getStatus()))
                    .map(TangNousInfo::getBid).collect(Collectors.toList());

            if(EmptyChecker.notEmpty(bidList)){

                TangStageInfo condition = (TangStageInfo) RxBaseData.create(TangStageInfo.class, HANDLER_TYPE.SINGLE_LIST);
                Map<String,Object> map = new HashMap();
                map.put("inNousBid",bidList);
                List<TangStageInfo> stageInfoList = (List<TangStageInfo>) standardService.searchList(condition);

                if (EmptyChecker.notEmpty(stageInfoList)){
                    // 分组
                    Map<String,List<TangStageInfo>> mapList = stageInfoList.stream().collect(Collectors.groupingBy(e->e.getNousBid()));


                    for (DoubleTangNousInfo tangNousInfo : resultList) {
                        List<TangStageInfo> stageInfos =  mapList.get(tangNousInfo.getBid());
                        tangNousInfo.setStageList(stageInfos);
                    }
                }
            }


        }

        return resultList;
    }


    public Object latestColmunist() throws InstantiationException, IllegalAccessException {

        // 返回最新的寄语
        TangColumnistInfo condition;
        Integer maxId = new Integer(MIN_RETURN_SIZE);
        try {
            condition = (TangColumnistInfo) RxBaseData.create(TangColumnistInfo.class, HANDLER_TYPE.SINGLE_LIST);
            condition.setIsNewest(NEWEST);
            return standardService.searchList(condition);
        } catch (Throwable e) {
            return null;
        }
    }
    public  Object rudimentaryBook(TangBookInfo param){
        try {
            RxBaseData.create(param,HANDLER_TYPE.SINGLE_LIST);
            // TODO:缓存
            param.setType(BOOK_TYPE_MENG);
            return standardService.searchList(param);
        } catch (IllegalAccessException | InstantiationException e) {
            return null;
        }
    }
    public  Object bookPage(TangBookInfo param){
        try {
            RxBaseData.create(param,HANDLER_TYPE.SINGLE_PAGE);
            return standardService.searchPage(param);
        } catch (IllegalAccessException | InstantiationException e) {
            return null;
        }
    }
    public  Object articlePage(TangArticleInfo param){
        try {
            RxBaseData.create(param,HANDLER_TYPE.SINGLE_PAGE);
            return standardService.searchPage(param);
        } catch (IllegalAccessException | InstantiationException e) {
            return null;
        }
    }
    public Object bookComment(TangCommentInfo param){
        try {
            RxBaseData.create(param,HANDLER_TYPE.SINGLE_PAGE);
            return standardService.searchPage(param);
        } catch (IllegalAccessException | InstantiationException e) {
            return null;
        }
    }

    public Object bookSeal(TangSealInfo param){
        try {
            RxBaseData.create(param,HANDLER_TYPE.SINGLE_PAGE);
            return standardService.searchPage(param);
        } catch (IllegalAccessException | InstantiationException e) {
            return null;
        }
    }
    public Object bookNotes(TangNotesInfo param){
        try {
            if(EmptyChecker.isEmpty(param.getUserBid())){
                return null;
            }
            RxBaseData.create(param,HANDLER_TYPE.SINGLE_PAGE);
            return standardService.searchPage(param);
        } catch (IllegalAccessException | InstantiationException e) {
            return null;
        }
    }
    public MainHelloVo hello(MainHelloVo mainService){

        SimpleDateFormat formatter = new SimpleDateFormat(RxBaseConstant.DATE_FORMAT_DATETIME.trim());
        String dateString = formatter.format(new Date()).trim();
        String md5 = RxUtil.EncryptUtil.toMD5(dateString.substring(0,16));
        if(!md5.equalsIgnoreCase(mainService.getSequences())){
            // return mainService;
        }
        // 以后改成数据库
        ReadProperties.loadConfig(rxMainConfigBean);

        mainService.setAdFileName(rxMainConfigBean.getAdFileName());
        mainService.setAppVersion(rxMainConfigBean.getAppVersion());
        mainService.setAdShow(rxMainConfigBean.getAdShow());
        mainService.setAppApk(rxMainConfigBean.getAppApk());


        return  mainService;
    }

    public String downloadFile(HttpServletResponse response,String filePath, String fileName, boolean notIE) {
        File file = new File(filePath + fileName);

        FileInputStream stream = null;
        try {
            stream = new FileInputStream(file);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }
        String type = "application/octet-stream";
        //InputStream stream = FileUtil.class.getClassLoader().getResourceAsStream("app/" + fileName);
        String[] strArray = fileName.split("\\.");
        int suffixIndex = strArray.length -1;
        //System.out.println(strArray[suffixIndex]);
        if( "jpg".equalsIgnoreCase(strArray[suffixIndex]) ){
            type = "image/jpeg";
        }else if("png".equalsIgnoreCase(strArray[suffixIndex]) ){
            type = "image/png";
        }else if("bmp".equalsIgnoreCase(strArray[suffixIndex]) ){
            type = "application/x-bmp";
        }else if("gif".equalsIgnoreCase(strArray[suffixIndex]) ){
            type = "image/gif";
        }
        //response.setHeader("content-type", type);
        response.setContentType(type);
        try {
            String name = java.net.URLEncoder.encode(fileName, "UTF-8");
            if (notIE) {
                name = java.net.URLDecoder.decode(name, "ISO-8859-1");
            }
            response.setHeader("Content-Disposition", "attachment;filename=" + name );
        } catch (UnsupportedEncodingException e2) {
            e2.printStackTrace();
        }

        log.debug("开始");
        byte[] buff = new byte[1024];
        BufferedInputStream bis = null;
        OutputStream os = null;
        try {
            os = response.getOutputStream();
            bis = new BufferedInputStream(stream);

            int total = 0;
            int length;
            while ((length = bis.read(buff)) != -1) {
                // 后面的length 关键
                os.write(buff, 0, length);
                os.flush();
                total += length;
            }
            System.out.println("total:" + total);
        } catch (FileNotFoundException e1) {
            //e1.getMessage()+"系统找不到指定的文件";
            return "系统找不到指定的文件";
        }catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (bis != null) {
                try {
                    bis.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return "success";
    }

    public Object columnistPage(@Valid @RequestBody ColumnistInfoVo data) throws InstantiationException, IllegalAccessException {

        TangColumnistInfo condition =(TangColumnistInfo) RxBaseData.create(TangColumnistInfo.class,HANDLER_TYPE.SINGLE_PAGE);
        condition.setPageNum(data.getPageNum());
        condition.setPageSize(data.getPageSize());
        condition.setTmpVar(SuiTangHandler.AUTH_KEY,false);
        if(EmptyChecker.notEmpty(data.getTitle())){
            Map<String,Object> conditonLike = data.getCondition();
            if(conditonLike == null){
                conditonLike = new HashMap<>();
            }
            conditonLike.put(RX_DB_OPERATE.LIKE_RIGHT.getKey("title"),data.getTitle());
            condition.setCondition(conditonLike);
        }

        return standardService.searchPage(condition);
    }

    private String getFrefixName(String date){
        StringBuilder stringBuilder = new StringBuilder(RxBaseConstant.LOCAL_FILE_PREFIX);
        return stringBuilder.append(date).append("_").toString();
    }
    protected HttpServletRequest getRequest(){
        return ((ServletRequestAttributes) (RequestContextHolder.currentRequestAttributes())).getRequest();
    }

    public Object upload(MultipartFile parameterFilename){
        String date = RxUtil.RxDate.data();
        String folderString = getFrefixName(date);
        File folder = new File(rxMainConfigBean.getImagePath() + date);
        if (!folder.exists() && !folder.isDirectory()) {
            folder.mkdirs();
        }

        date+="/";
        String oriFilename = parameterFilename.getOriginalFilename();
        if(oriFilename.length() > 24){
            oriFilename = oriFilename.substring(oriFilename.length() - 24);
        }
        String fileName = folderString + oriFilename;
        File file = new File(rxMainConfigBean.getImagePath() + date + fileName);
        int count = 1;

        while (file.exists()){
            fileName = folderString  + count+"_" + oriFilename;
            file = new File(rxMainConfigBean.getImagePath() + date + fileName);
            count++;
        }
        try {
            FileUtils.copyInputStreamToFile(parameterFilename.getInputStream(),file);
        } catch (IOException e) {
            e.printStackTrace();
        }
        FileInfoResult fileInfoResult = new FileInfoResult();
        fileInfoResult.setFileName(fileName);
        fileInfoResult.setFileType(RxBaseConstant.LOCAL_FILE_PREFIX);
        fileInfoResult.setMessage("上传成功");
        fileInfoResult.setCode("0");
        // TODO: 注意微服务。
        fileInfoResult.setUrl("/api/uua/common/image-download?fileName="+fileName+"&fileType=");
        return fileInfoResult;
    }
}
